﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;

namespace EYangFramework.Common.BasicHelper
{
    public class SerializeHelper
    {
        private object objlock = new object();
        public string SerializeObject(object obj)
        {
            JavaScriptSerializer js = new JavaScriptSerializer();
            return js.Serialize(obj);
        }
        public T DeserializeFromJson<T>(string jsonString)
        {
            JavaScriptSerializer js = new JavaScriptSerializer();
            return js.Deserialize<T>(jsonString);
        }

        public object DeserializeFromJson(string jsonString, Type type)
        {
            JavaScriptSerializer js = new JavaScriptSerializer();
            return js.Deserialize(jsonString, type);
        }

        public void SerializeObjectToFile(string fileName, object obj)
        {
            string jsonString = SerializeObject(obj);
            using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
            {
                lock (objlock)
                {
                    byte[] bytes = Encoding.Default.GetBytes(jsonString);
                    fs.Write(bytes, 0, bytes.Length);
                    fs.Flush();
                }
            }
        }
        public T DeserializeFromFile<T>(string fileName)
        {
            if (!File.Exists(fileName))
            {
                throw new FileNotFoundException($"{fileName}文件不存在!");
            }
            using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                byte[] buffer = new byte[fs.Length];
                fs.Read(buffer, 0, buffer.Length);
                string jsonString = Encoding.Default.GetString(buffer);
                return DeserializeFromJson<T>(jsonString);
            }
        }
        public void SerializerObjectToTemp(List<TempObject> tempObjects)
        {
            string tempFilePath = Path.Combine(ConfigurationManager.AppSettings["TempFilePath"], $"{DateTime.Now.ToString("yyyyMMddHHmmss")}.json");
            List<TempObject> lastObjects = new List<TempObject>();
            //如果当前文件的文件已经存在,则将对应的类型添加进文件中
            if (File.Exists(tempFilePath))
            {
                lastObjects = DeserializeFromFile<List<TempObject>>(tempFilePath);
            }
            tempObjects.AddRange(lastObjects);
            SerializeObjectToFile(tempFilePath, tempObjects);
        }
        public List<TempObject> DeserializeFromTemp()
        {
            List<TempObject> tempObjects = new List<TempObject>();
            string tempFilePath = ConfigurationManager.AppSettings["TempFilePath"];
            if (!Directory.Exists(tempFilePath))
            {
                throw new DirectoryNotFoundException($"{tempFilePath}路径不存在!");
            }
            string[] files = Directory.GetFiles(tempFilePath);
            foreach (var file in files)
            {
                tempObjects.AddRange(DeserializeFromFile<List<TempObject>>(file));
                Directory.Delete(file);//获取到缓存的数据之后,将原始文件删除掉
            }
            return tempObjects;
        }
        /// <summary>
        /// 此类用于缓存数据到文件中,防止在网络断了之后出现数据丢失的情况
        /// </summary>
        public class TempObject
        {
            public string DataType { get; set; }
            public string Instance { get; set; }
            public int EntityState { get; set; }//用于保存实体的类型,0表示Add,1表示Modify,2表示Deleted

            public TempObject() { }
            public TempObject(Type dataType, object obj, int state)
            {
                DataType = $"{dataType.FullName},{dataType.Assembly.FullName}";
                Instance = new SerializeHelper().SerializeObject(obj);
                EntityState = state;
            }
            public TempObject(string typeFullName, object obj, int state)
            {
                DataType = typeFullName;
                Instance= new SerializeHelper().SerializeObject(obj);
                EntityState = state;
            }
            public TempObject(string typeFullName, string instance, int state)
            {
                DataType = typeFullName;
                Instance = instance;
                EntityState = state;
            }
        }
    }
}
